package org.csu.mypetstore.proxy;

//import com.sun.tools.javac.util.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.csu.mypetstore.domain.Account;
import org.csu.mypetstore.domain.Log;
import org.csu.mypetstore.domain.Order;
import org.csu.mypetstore.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

@Aspect
@Component
public class LogProxy {
//    @Autowired
//    HttpServletRequest request;
    @Autowired
    HttpSession session;
    @Autowired
    LogService logService;


    @After( value = "execution( * org.csu.mypetstore.controller.AccountController.login(..))")
    public void insertLoginLog(){
        Account account = (Account) session.getAttribute( "account" );
        if ( account != null && account.isAuthenticated() ){
            Log log = new Log( account.getUsername(), Log.LOG_IN, "Successfully" );
            logService.insertLogInfo( log );
        }
    }

    //由于signout之后session中的account参数会被置为null, 因此要用前置建议
    @Before( value = "execution( * org.csu.mypetstore.controller.AccountController.signout(..))" )
    public void insertSignoutLog(){
        Account account = (Account) session.getAttribute( "account" );
        if ( account != null && account.isAuthenticated() ){
            Log log = new Log( account.getUsername(), Log.SIGN_OUT, "" );
            logService.insertLogInfo( log );
        }
    }

    @After( value = "execution( * org.csu.mypetstore.controller.CartController.addItemToCart(..))" )
    public void insertAddItemToCartLog( JoinPoint joinPoint ){
        Account account = (Account) session.getAttribute( "account" );
        if ( account != null && account.isAuthenticated() ){
            String description = "Add Item";
            //获取切入点的方法参数
            String parameter = "";
            Object[] args = joinPoint.getArgs();
            //获取记录商品ID对应的参数在参数表中下标
            String[] parameterNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
            int index = -1;
            for( int i = 0; i < parameterNames.length; i ++ ){
                if( parameterNames[i].equals( "workingItemId" ) ){
                    index = i;
                }
            }
            //若找到指定参数下标
            if( index != -1 ){
                parameter += ( ", Item ID: " + args[index] );
            }

            if(!parameter.isEmpty()){
                description += parameter;
            }
            Log log = new Log( account.getUsername(), Log.UPDATE_CART, description );
            logService.insertLogInfo( log );
        }
    }

    @After( value = "execution( * org.csu.mypetstore.controller.CartController.removeItemFromCart(..))" )
    public void insertRemoveItemFromCartLog( JoinPoint joinPoint ){
        Account account = (Account) session.getAttribute( "account" );
        if ( account != null && account.isAuthenticated() ){
            String description = "Remove Item";
            //获取切入点的方法参数
            String parameter = "";
            Object[] args = joinPoint.getArgs();
            //获取记录商品ID对应的参数在参数表中下标
            String[] parameterNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
            int index = -1;
            for( int i = 0; i < parameterNames.length; i ++ ){
                if( parameterNames[i].equals( "workingItemId" ) ){
                    index = i;
                }
            }
            //若找到指定参数下标
            if( index != -1 ){
                parameter += ( ", Item ID: " + args[index] );
            }

            if(!parameter.isEmpty()){
                description += parameter;
            }
            Log log = new Log( account.getUsername(), Log.UPDATE_CART, description );
            logService.insertLogInfo( log );
        }
    }

    @After( value = "execution( * org.csu.mypetstore.controller.CatalogController.*(..))" )
    public void insertViewLog( JoinPoint joinPoint ){
        Account account = (Account) session.getAttribute( "account" );
        if ( account != null && account.isAuthenticated() ){
            //获取切入点方法名
            String description = joinPoint.getSignature().getName();
            //转换为首字母大写
            description = description.substring( 0, 1 ).toUpperCase()+description.substring( 1 );
            if(description == "View"){
                description = "View Main";
            }else if(description.startsWith( "View" )){
                //在View和类别之间加上空格，增强日志可读性
                description = description.substring( 0, 4 ) + " " + description.substring( 4 );
            }
            //获取切入点的方法参数
            String parameter = "";
            Object args[] = joinPoint.getArgs();
            //对描述字符串进行拼接
            for(Object arg: args){
                if(arg instanceof String){
                    if(parameter.isEmpty()){
                        parameter = (String) arg;
                    }else {
                        parameter += ", " + arg;
                    }
                }
            }
            if(!parameter.isEmpty()){
                description += ", Parameter: " + parameter;
            }
            Log log = new Log( account.getUsername(), Log.VIEW, description );
            logService.insertLogInfo( log );
        }
    }

    @After( value = "execution( * org.csu.mypetstore.controller.OrderController.comfirmOrder(..))" )
    public void insertConfirmOrderLog( JoinPoint joinPoint ){
        Account account = (Account) session.getAttribute( "account" );
        Order order = (Order) session.getAttribute( "order" );
        if ( account != null && account.isAuthenticated() && order != null ){
            String description = "Order ID: " + order.getOrderId();
            Log log = new Log( account.getUsername(), Log.SUBMIT_ORDER, description );
            logService.insertLogInfo( log );
        }
    }

    @After( value = "execution( * org.csu.mypetstore.controller.OrderController.viewOrderByOrderId(..))" )
    public void insertViewOrderLog( JoinPoint joinPoint ){
        Account account = (Account) session.getAttribute( "account" );
        Order order = (Order) session.getAttribute( "order" );
        if ( account != null && account.isAuthenticated() && order != null ){
            String description = "View Order";
            //获取切入点的方法参数
            String parameter = "";
            Object[] args = joinPoint.getArgs();
            //获取记录商品ID对应的参数在参数表中下标
            String[] parameterNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
            int index = -1;
            for( int i = 0; i < parameterNames.length; i ++ ){
                if( parameterNames[i].equals( "orderId" ) ){
                    index = i;
                }
            }
            //若找到指定参数下标
            if( index != -1 ){
                parameter += ( ", Order ID: " + args[index] );
            }

            if(!parameter.isEmpty()){
                description += parameter;
            }
            Log log = new Log( account.getUsername(), Log.VIEW, description );
            logService.insertLogInfo( log );
        }
    }









}
